<template>
  <view class="captcha-container">
    <view class="captcha-wrapper" :class="{ 'loading': loading }">
      <canvas
        canvas-id="captcha-canvas"
        class="captcha-canvas"
        :style="{ width: width + 'px', height: height + 'px' }"
        @tap="refreshCaptcha"
      ></canvas>
      <!-- 加载遮罩 -->
      <view v-if="loading" class="loading-mask">
        <view class="loading-spinner"></view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'Captcha',
  props: {
    width: {
      type: Number,
      default: 120
    },
    height: {
      type: Number,
      default: 48
    },
    length: {
      type: Number,
      default: 4
    },
    // 是否显示加载状态
    loading: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      captchaCode: '',
      ctx: null,
      isRefreshing: false
    }
  },
  mounted() {
    this.initCaptcha()
  },
  methods: {
    // 初始化验证码
    initCaptcha() {
      this.ctx = uni.createCanvasContext('captcha-canvas', this)
      this.generateCaptcha()
    },
    
    // 生成验证码
    generateCaptcha() {
      const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
      let code = ''
      
      // 生成随机验证码
      for (let i = 0; i < this.length; i++) {
        code += chars.charAt(Math.floor(Math.random() * chars.length))
      }
      
      this.captchaCode = code
      this.drawCaptcha(code)
      
      // 通知父组件验证码已生成
      this.$emit('generated', code)
    },
    
    // 绘制验证码
    drawCaptcha(code) {
      const ctx = this.ctx

      // 清空画布
      ctx.clearRect(0, 0, this.width, this.height)

      // 设置渐变背景
      const gradient = ctx.createLinearGradient(0, 0, this.width, this.height)
      gradient.addColorStop(0, '#f8f9ff')
      gradient.addColorStop(0.5, '#ffffff')
      gradient.addColorStop(1, '#f0f4ff')
      ctx.fillStyle = gradient
      ctx.fillRect(0, 0, this.width, this.height)

      // 绘制装饰性背景图案
      ctx.strokeStyle = 'rgba(64, 128, 255, 0.05)'
      ctx.lineWidth = 1
      for (let i = 0; i < 3; i++) {
        ctx.beginPath()
        ctx.arc(Math.random() * this.width, Math.random() * this.height,
               10 + Math.random() * 20, 0, 2 * Math.PI)
        ctx.stroke()
      }

      // 绘制优雅的干扰线
      for (let i = 0; i < 3; i++) {
        ctx.strokeStyle = `rgba(64, 128, 255, ${0.1 + Math.random() * 0.2})`
        ctx.lineWidth = 1 + Math.random()
        ctx.beginPath()
        const startX = Math.random() * this.width
        const startY = Math.random() * this.height
        const endX = Math.random() * this.width
        const endY = Math.random() * this.height

        // 绘制贝塞尔曲线
        const cpX = (startX + endX) / 2 + (Math.random() - 0.5) * 30
        const cpY = (startY + endY) / 2 + (Math.random() - 0.5) * 30
        ctx.moveTo(startX, startY)
        ctx.quadraticCurveTo(cpX, cpY, endX, endY)
        ctx.stroke()
      }

      // 绘制验证码字符
      for (let i = 0; i < code.length; i++) {
        const char = code[i]
        const x = (this.width / code.length) * i + (this.width / code.length) / 2
        const y = this.height / 2

        // 字符颜色使用主题色系
        const colors = ['#4080FF', '#1890FF', '#2f54eb', '#722ed1', '#eb2f96']
        ctx.fillStyle = colors[i % colors.length]

        // 字体大小和样式 - 根据高度调整
        const fontSize = Math.max(16, this.height * 0.4 + Math.random() * 4)
        ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`
        ctx.textAlign = 'center'
        ctx.textBaseline = 'middle'

        // 添加文字阴影效果
        ctx.shadowColor = 'rgba(64, 128, 255, 0.3)'
        ctx.shadowBlur = 1
        ctx.shadowOffsetX = 1
        ctx.shadowOffsetY = 1

        // 随机旋转角度（减小旋转幅度）
        const angle = (Math.random() - 0.5) * 0.2
        ctx.save()
        ctx.translate(x, y)
        ctx.rotate(angle)
        ctx.fillText(char, 0, 0)
        ctx.restore()

        // 清除阴影设置
        ctx.shadowColor = 'transparent'
        ctx.shadowBlur = 0
        ctx.shadowOffsetX = 0
        ctx.shadowOffsetY = 0
      }

      // 绘制精致的干扰点
      for (let i = 0; i < 20; i++) {
        ctx.fillStyle = `rgba(64, 128, 255, ${0.1 + Math.random() * 0.3})`
        ctx.beginPath()
        ctx.arc(Math.random() * this.width, Math.random() * this.height,
               0.5 + Math.random() * 1.5, 0, 2 * Math.PI)
        ctx.fill()
      }

      ctx.draw()
    },
    
    // 获取随机颜色
    getRandomColor(min, max) {
      const r = Math.floor(Math.random() * (max - min) + min)
      const g = Math.floor(Math.random() * (max - min) + min)
      const b = Math.floor(Math.random() * (max - min) + min)
      return `rgb(${r}, ${g}, ${b})`
    },
    
    // 刷新验证码
    refreshCaptcha() {
      if (this.isRefreshing) return

      this.isRefreshing = true
      this.$emit('refresh-start')

      // 添加延迟，让用户看到刷新动画
      setTimeout(() => {
        this.generateCaptcha()
        this.isRefreshing = false
        this.$emit('refresh-end')
      }, 300)
    },
    
    // 验证验证码
    validate(inputCode) {
      return inputCode.toLowerCase() === this.captchaCode.toLowerCase()
    },
    
    // 获取当前验证码
    getCode() {
      return this.captchaCode
    }
  }
}
</script>

<style scoped>
.captcha-container {
  display: inline-block;
  width: 100%;
}

.captcha-wrapper {
  position: relative;
  display: inline-block;
  width: 100%;
  border-radius: 12rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 8rpx rgba(64, 128, 255, 0.1);
  transition: all 0.3s ease;
  background: #fff;
  border: 2rpx solid #eee;
}

.captcha-wrapper:hover {
  border-color: #4080FF;
  box-shadow: 0 0 0 6rpx rgba(64, 128, 255, 0.1);
}

.captcha-canvas {
  display: block;
  width: 100% !important;
  cursor: pointer;
  transition: opacity 0.3s ease;
}

.captcha-canvas:active {
  opacity: 0.8;
}



/* 加载动画 */
.captcha-wrapper.loading {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0% {
    box-shadow: 0 4rpx 12rpx rgba(64, 128, 255, 0.15);
  }
  50% {
    box-shadow: 0 4rpx 12rpx rgba(64, 128, 255, 0.3);
  }
  100% {
    box-shadow: 0 4rpx 12rpx rgba(64, 128, 255, 0.15);
  }
}

/* 加载遮罩 */
.loading-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12rpx;
}

.loading-spinner {
  width: 24rpx;
  height: 24rpx;
  border: 3rpx solid #f3f3f3;
  border-top: 3rpx solid #4080FF;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 响应式设计 */
@media screen and (max-width: 400px) {
  .refresh-btn {
    width: 28rpx;
    height: 28rpx;
    top: -6rpx;
    right: -6rpx;
  }

  .refresh-icon {
    font-size: 18rpx;
  }

  .tip-text {
    font-size: 22rpx;
  }

  .loading-spinner {
    width: 20rpx;
    height: 20rpx;
    border-width: 2rpx;
  }
}
</style>
